package gatperdut.chato.core.interpreter.actions;

import gatperdut.chato.constants.CSConstantsCommandResult.CommandExecutionResult;
import gatperdut.chato.core.characters.BaseController;
import gatperdut.chato.core.interpreter.actions.generic.Action;
import gatperdut.chato.core.interpreter.grammar.comminfo.FoodInfo;
import gatperdut.chato.core.item.DrinkController;
import gatperdut.chato.core.item.FoodController;
import gatperdut.chato.core.item.ItemController;
import gatperdut.chato.core.item.inventory.InventoryController;

public class FoodAction extends Action {

    public FoodAction( FoodInfo info, BaseController entityController ) {
        super( info, entityController );
    }

    @Override
    public CommandExecutionResult perform() {
        checkForRunningCraft();

        if ( emptyEmote() ) {
            getEntityController().tx( "Empty emotes are not allowed." );
            return CommandExecutionResult.OK;
        }

        String emote = getLastPartEmote();
        if ( emote == null ) {
            getEntityController().tx( "Check your emote." );
            return CommandExecutionResult.OK;
        }

        ItemController ic = null;
        InventoryController inventoryControllerFoodIsIn = null;
        if ( !getInfo().isGround() ) {
            inventoryControllerFoodIsIn = getEntityController().getInventoryController();
        }
        if ( getInfo().isGround() || ( !getInfo().isGround() && inventoryControllerFoodIsIn == null ) ) {
            inventoryControllerFoodIsIn = getEntityController().getRoomController().getInventoryController();
        }
        synchronized ( inventoryControllerFoodIsIn ) {
            ic = findInRoomOrInventory( getInfo().getWhat(), getInfo().isGround() );
            if ( ic == null ) {
                getEntityController().tx( "You can't find that." );
                return CommandExecutionResult.OK;
            }

            synchronized ( ic ) {
                int amountToConsume = getInfo().getAmount();

                switch ( getInfo().getConsumptionType() ) {
                case DRINK:
                    DrinkController dc = (DrinkController) ic.getAmountController();
                    if ( !ic.isDrinkable() ) {
                        getEntityController().tx( "You cannot drink from " + ic.getShortDesc() + "." );
                        return CommandExecutionResult.OK;
                    }
                    if ( dc.hasNoPortionLeft() ) {
                        getEntityController().tx( ic.getShortDesc() + " is empty." );
                        return CommandExecutionResult.OK;
                    }
                    if ( !dc.canAffordPortionDecrease( amountToConsume ) ) {
                        getEntityController().tx( "There's not that much to be quaffed from " + ic.getShortDesc() + "." );
                        return CommandExecutionResult.OK;
                    }
                    getEntityController().getEchoes().txDrink( ic, amountToConsume, emote );
                    dc.consumePortion( amountToConsume );
                    if ( dc.isSetWithEmptyContainerOnTop() ) {
                        ItemController emptyContainer = ic.spawnFromSetOfNonEmptyContainers();
                        getEntityController().handleSpawnedItem( ic.getContainerController(), emptyContainer );
                    }
                    break;
                case EAT:
                    FoodController fc = (FoodController) ic.getAmountController();
                    if ( !ic.isEatable() ) {
                        getEntityController().tx( "You cannot eat " + ic.getShortDesc() + "." );
                        return CommandExecutionResult.OK;
                    }
                    if ( !fc.canAffordPortionDecrease( amountToConsume ) ) {
                        getEntityController().tx( "There's not that much to be eaten from " + ic.getShortDesc() + "." );
                        return CommandExecutionResult.OK;
                    }
                    getEntityController().getEchoes().txEat( ic, amountToConsume, emote );
                    fc.consumePortion( amountToConsume );
                    if ( fc.getPortion() == 0 ) {
                        if ( fc.getCurrent() == 1 ) {
                            ic.junk();
                        }
                        else {
                            fc.decrease( 1 );
                            fc.setToMaxPortion();
                        }
                    }
                    break;
                default:
                    throw new IllegalArgumentException( "Food action with unknown consumption type." );
                }

            }
        }
        return CommandExecutionResult.OK;
    }

    @Override
    public boolean interruptsCrafting() {
        return false;
    }

    @Override
    public FoodInfo getInfo() {
        return (FoodInfo) super.getInfo();
    }

}
